package com.qf.fmall.user.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.fmall.user.entity.User;
import com.qf.fmall.user.mapper.UserMapper;
import com.qf.fmall.user.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.fmall.user.vo.LoginVo;
import com.qf.fmall.user.vo.RegisterVo;
import com.qf.fmall.utils.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;


/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wbw
 * @since 2023-11-27
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired  //等于this.baseMapper
    private UserMapper userMapper;

    /**
     * 注册逻辑
     * @param registerVo 注册接收的参数
     * @return
     */
    @Override
    public boolean regist(RegisterVo registerVo) {
        //1.检查用户名是否重复
        String username = registerVo.getUsername();

        //查询指定用户名
        User deUser = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (deUser != null) {
            log.info("注册用户时用户名已存在，username={}", username);
        }

        //2.把用户的数据写入user表中
        User user = new User();
        user.setUsername(username);
        user.setPassword(registerVo.getPassword());
        //密码处理
        String password = registerVo.getPassword();
        //处理为Md5 形式的字符串
        // 生成一个随机盐
        String salt = UUID.randomUUID().toString().substring(0, 8);
        user.setSalt(salt);
        String md5Password = DigestUtil.md5Hex(password + salt);
        user.setPassword(md5Password);


        user.setUserRegtime(new Date());
        user.setUserModtime(new Date());
        userMapper.insert(user);
        return true;
    }

    /**
     * 登录逻辑
     * @param username
     * @param password
     * @return LoginVo  接收登陆的参数
     */
    @Override
    public LoginVo login(String username, String password) {
        //1.根据username查询数据表，有没有对应的user数据，没有user登录失败
        User dbUser = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        LoginVo loginVo = new LoginVo();
        if (dbUser==null){
            log.info("没有找到对应的用户信息，用户名{}错误",username);
            loginVo.setStatus(false);//登录失败
            loginVo.setUser(null);
            return loginVo;
        }
        //2.比对密码是否一致

        //先把传过来的密码按照salt和md5计算
        String salt = dbUser.getSalt();
        String dbpassword = dbUser.getPassword();
        String md5password = DigestUtil.md5Hex(password + salt);

        if (!dbpassword.equals(md5password)){
            log.info("用户名或者密码错误");
            loginVo.setStatus(false);//登录失败
            return loginVo;//返回
        }
        //3.处理token的生成
//        String token = creatJWT(dbUser);
        String token = TokenUtils.createToke(dbUser);
        loginVo.setStatus(true);
        dbUser.setSalt(null);//去掉salt
        loginVo.setUser(dbUser);
        loginVo.setToken(token);
        log.info("用户登录成功：username={},token={}",username,token);
        return loginVo;
    }

    /**
     * 当用户输入正确的账户和密码是会创建一个token
     * 当用户再访问每个接口时，能提供一个正确的token,说明用户曾经登陆过
     *
     * 1.让服务端可以校验token的合法性，（这个token是不是我么自己的服务器颁发的）
     * 2.token需要可以校验时效性（超过时间）
     * 3.token可以携带自定义数据
     * token通常携带的数据有：用户标识、（可以保存用户的全部信息）
     * @return
     */
    private  String createJWT(User user){
        String toke = TokenUtils.createToke(user);
        return toke;
    }
}
